﻿using System.ComponentModel;
using System.Threading;
namespace Bango.WindowsPhone7_5.SDK
{
	internal class BangoPoster
	{
		internal IBangoPostable Profile { get; set; }
		internal BangoLogger Logger { get; set; }
		private BangoProfile profileToPost;
		private System.Boolean postResult;

		private ManualResetEvent postingReset = new ManualResetEvent(true);

		internal BangoPoster(BangoLogger logger, IBangoPostable storedProfileToPost)
		{
			Logger = logger;
			Profile = storedProfileToPost;
		}

		internal void PostEvents()
		{
			postingReset.WaitOne();

			postingReset.Reset();

			try
			{
				PostEventsForProfile();
			}
			catch (System.Exception ex)
			{
				System.Console.WriteLine(ex.Message);
				postingReset.Set();
			}
		}

		/// <summary>
		/// Posts the supplied profile and associated events to the specified url.
		/// </summary>
		/// <returns>Whether or not the profile and associated events were posted successfully.</returns>
		private System.Boolean PostEventsForProfile()
		{
			System.Net.HttpWebRequest request;

			try
			{
				request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(Logger.PostURL);
				request.Method = "POST";
				request.ContentType = "application/json";

				if (!string.IsNullOrEmpty(Logger.UserAgent))
				{
					request.Headers["User-Agent"] = Logger.UserAgent;
				}
				request.BeginGetRequestStream(new System.AsyncCallback(GetRequestStreamCallback), request);
			}
			catch (System.Exception)
			{
				postResult = false;
			}

			return postResult;
		}

		private void GetRequestStreamCallback(System.IAsyncResult asynchronousResult)
		{
			System.Net.HttpWebRequest request;
			System.Runtime.Serialization.Json.DataContractJsonSerializer jsonSerializer;
			System.String postData = System.String.Empty;
			System.Byte[] postBytes;

			try
			{
				profileToPost = Profile.GetPostProfile();
				request = (System.Net.HttpWebRequest)asynchronousResult.AsyncState;
				using (System.IO.Stream postStream = request.EndGetRequestStream(asynchronousResult))
				{
					jsonSerializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(BangoProfile));
					using (System.IO.MemoryStream jsonMemory = new System.IO.MemoryStream())
					{
						jsonSerializer.WriteObject(jsonMemory, profileToPost);

						using (System.IO.StreamReader jsonStream = new System.IO.StreamReader(jsonMemory))
						{
							jsonMemory.Position = 0;
							postData = jsonStream.ReadToEnd();
						}
					}

					postBytes = System.Text.Encoding.UTF8.GetBytes(postData);
					postStream.Write(postBytes, 0, postBytes.Length);
					postStream.Close();
				}
				// Start the asynchronous operation to get the response
				request.BeginGetResponse(new System.AsyncCallback(GetResponseCallback), request);
			}
			catch (System.Exception)
			{
				postingReset.Set();
			}
		}

		private void GetResponseCallback(System.IAsyncResult asynchronousResult)
		{
			System.Net.HttpWebRequest request;
			System.Net.HttpWebResponse response;
			try
			{
				request = (System.Net.HttpWebRequest)asynchronousResult.AsyncState;
				using (response = (System.Net.HttpWebResponse)request.EndGetResponse(asynchronousResult))
				{

					postResult = (response.StatusCode == System.Net.HttpStatusCode.OK);
					response.Close();
				}

				Profile.UpdatePostedEvents();

			}
			catch (System.Exception)
			{
			}
			finally
			{
				postingReset.Set();
			}

		}
	}

	internal interface IBangoPostable
	{
		BangoProfile GetPostProfile();
		void UpdatePostedEvents();
	}
}
